﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace AdventureWorksLT.Core
{
public class EventToCommand : TriggerAction<DependencyObject>
{
    // Fields
    private object _commandParameterValue;
    private bool? _mustToggleValue;
    public static readonly DependencyProperty CommandParameterProperty;
    public static readonly DependencyProperty CommandProperty;
    public static readonly DependencyProperty MustToggleIsEnabledProperty;

    // Methods
    static EventToCommand()
    {
        CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventToCommand), new PropertyMetadata(null, delegate (DependencyObject s, DependencyPropertyChangedEventArgs e) {
            EventToCommand sender = s as EventToCommand;
            if ((sender != null) && (sender.AssociatedObject != null))
            {
                sender.EnableDisableElement();
            }
        }));
        CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommand), new PropertyMetadata(null, delegate (DependencyObject s, DependencyPropertyChangedEventArgs e) {
            OnCommandChanged(s as EventToCommand, e);
        }));
        MustToggleIsEnabledProperty = DependencyProperty.Register("MustToggleIsEnabled", typeof(bool), typeof(EventToCommand), new PropertyMetadata(false, delegate (DependencyObject s, DependencyPropertyChangedEventArgs e) {
            EventToCommand sender = s as EventToCommand;
            if ((sender != null) && (sender.AssociatedObject != null))
            {
                sender.EnableDisableElement();
            }
        }));
    }

    private bool AssociatedElementIsDisabled()
    {
        Control element = this.GetAssociatedObject();
        return ((base.AssociatedObject == null) || ((element != null) && !element.IsEnabled));
    }

    private void EnableDisableElement()
    {
        Control element = this.GetAssociatedObject();
        if (element != null)
        {
            ICommand command = this.GetCommand();
            if (this.MustToggleIsEnabledValue && (command != null))
            {
                element.IsEnabled = command.CanExecute(this.CommandParameterValue);
            }
        }
    }

    private Control GetAssociatedObject()
    {
        return (base.AssociatedObject as Control);
    }

    private ICommand GetCommand()
    {
        return this.Command;
    }

    public void Invoke()
    {
        this.Invoke(null);
    }

    protected override void Invoke(object parameter)
    {
        if (!this.AssociatedElementIsDisabled())
        {
            ICommand command = this.GetCommand();
            object commandParameter = this.CommandParameterValue;
            if ((commandParameter == null) && this.PassEventArgsToCommand)
            {
                commandParameter = parameter;
            }
            if ((command != null) && command.CanExecute(commandParameter))
            {
                command.Execute(commandParameter);
            }
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        this.EnableDisableElement();
    }

    private void OnCommandCanExecuteChanged(object sender, EventArgs e)
    {
        this.EnableDisableElement();
    }

    private static void OnCommandChanged(EventToCommand element, DependencyPropertyChangedEventArgs e)
    {
        if (element != null)
        {
            if (e.OldValue != null)
            {
                ((ICommand) e.OldValue).CanExecuteChanged -= new EventHandler(element.OnCommandCanExecuteChanged);
            }
            ICommand command = (ICommand) e.NewValue;
            if (command != null)
            {
                command.CanExecuteChanged += new EventHandler(element.OnCommandCanExecuteChanged);
            }
            element.EnableDisableElement();
        }
    }

    // Properties
    public ICommand Command
    {
        get
        {
            return (ICommand) base.GetValue(CommandProperty);
        }
        set
        {
            base.SetValue(CommandProperty, value);
        }
    }

    public object CommandParameter
    {
        get
        {
            return base.GetValue(CommandParameterProperty);
        }
        set
        {
            base.SetValue(CommandParameterProperty, value);
        }
    }

    public object CommandParameterValue
    {
        get
        {
            return (this._commandParameterValue ?? this.CommandParameter);
        }
        set
        {
            this._commandParameterValue = value;
            this.EnableDisableElement();
        }
    }

    public bool MustToggleIsEnabled
    {
        get
        {
            return (bool) base.GetValue(MustToggleIsEnabledProperty);
        }
        set
        {
            base.SetValue(MustToggleIsEnabledProperty, value);
        }
    }

    public bool MustToggleIsEnabledValue
    {
        get
        {
            return (!this._mustToggleValue.HasValue ? this.MustToggleIsEnabled : this._mustToggleValue.Value);
        }
        set
        {
            this._mustToggleValue = new bool?(value);
            this.EnableDisableElement();
        }
    }

    public bool PassEventArgsToCommand { get; set; }
}

 

 

}
